package winsplitter;

import ikelib.ChannelData;
import ikelib.SecondBlock;
import ikelib.wintime;
import ikelib.wintools;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import wcg.winchk;




//-----------------------------------------
// win ファイルの分割
public class winsplitter {

	private String Infile=null;
	private String OutDir=null;
	private int InfileLength=0;
	private byte[] InfileData=null;
	// 時刻のコレクション
	private TreeSet<wintime> WinTimeValue = new TreeSet<wintime>(); 
	// 秒チャンクのコレクション
	private TreeMap<Integer,byte[]> SecChunk = new TreeMap<Integer,byte[]>();
	
	public winsplitter(){
	}
	
	public String getOutDir() {
		return OutDir;
	}

	public void setOutDir(String outDir) {
		OutDir = outDir;
	}

	// ----------------------------------------------------
	// ----------------------------------------------------
	/**
	 * 時刻を指定してファイルに出力する
	 * @param set
	 * @return
	 */
	private int writeFileFromTimeSet(TreeSet<wintime> set){
		wintime wtm = set.first();
		String ofile = null;
		switch(LengthCode){
		case WIN_FILE_1MIN:	// 1minWIN
			ofile = wtm.fmtMinutFileName();
			break;
		case WIN_FILE_1HOUR:
			ofile = wtm.fmtHourFileName();
			break;
		default:
			return -1;
		}
		//ofile = OutDir+"\\"+ofile;
		ofile = OutDir + File.separator + ofile;
		File f = new File(ofile);
		int num = 0xa;
		String ext="";
		// ファイルが既にある場合は、拡張子を追加する。
		while(f.exists()){
			ext = String.format(".%x", num++);
			f = new File(ofile+ext);
		}
		ofile += ext;
		
		try{
			FileOutputStream out = new FileOutputStream(ofile);
			
			Iterator<wintime> ite = set.iterator();
			int count=0;
			while(ite.hasNext()){
				wintime tm = ite.next();
				byte[] dat = SecChunk.get(tm.getValueS());
				if(dat==null) break;
				out.write(dat);
				count += dat.length;
			}
			out.close();
			System.out.format("%s %dbyte\n",ofile,count);
		} catch(FileNotFoundException e){
			e.printStackTrace();
		} catch(IOException e){
			e.printStackTrace();
		}
		
		return 0;
	}
	// ----------------------------------------------------
	// ----------------------------------------------------
	/**
	 * １つのファイルを分割
	 * @param ifile
	 * @return
	 */
	public int Split(String ifile){
		try{
			FileInputStream in = new FileInputStream(ifile);
			InfileLength = in.available();
			InfileData = new byte[InfileLength];
			in.read(InfileData,0,InfileLength);
			in.close();
		}
		catch(Exception e){
			throw new RuntimeException(e);
		}
		
		int winFormat = winchk.getFileFormat(InfileData,InfileLength);
		switch(winFormat){
		case winchk.WIN_FORMAT_A0:
			break;
		case winchk.K_NET_CNTFILE:
			System.out.println("Input file " + ifile + " : unsupported format K-NET CNT");
			return -1;
		case winchk.TXT_FORMAT_KNET:
			System.out.println("Input file " + ifile + " : unsupported format K-NET ASCII");
			return -1;
		case winchk.WIN_FORMAT_A5:
			//System.out.println("Input file " + ifile + " : unsupported format win A5");
			//return -1;
			break;
		default:
			System.out.println("Input file " + ifile + " : unknown or unsupported format");
			return -1;
		}
		// Ａ５をサポートするために、Ａ０１秒チャンクデータに変換する。
		if(!wintools.convertSecChunk(InfileData,SecChunk,WinTimeValue)){
			return -2;	// フォーマットエラー
		}
		// 0秒のデータを見つけて
		TreeSet<wintime> tmpset=new TreeSet<wintime>();
		Iterator<wintime> ite = WinTimeValue.iterator();
		int count = 0;
		while(ite.hasNext()){
			wintime wtm = ite.next();
			tmpset.add(wtm);
			//System.out.println(wtm.fmt());
			switch(LengthCode){
			case WIN_FILE_1MIN:	// 1minWIN
				if(wtm.sec()==59){
					writeFileFromTimeSet(tmpset);
					count++;
					tmpset.clear();
				}
				break;
			case WIN_FILE_1HOUR:	// 1 hour WIN
			if(wtm.sec()==59 && wtm.min()==59){
				writeFileFromTimeSet(tmpset);
				count++;
				tmpset.clear();
			}
			break;
			}
		}
		// 最後のデータを出力する
		if(tmpset.size()!=0){
			switch(LengthCode){
			case WIN_FILE_1MIN:	// 1minWIN
				writeFileFromTimeSet(tmpset);
				count++;
				tmpset.clear();
				break;
			case WIN_FILE_1HOUR:	// 1 hour WIN
				writeFileFromTimeSet(tmpset);
				count++;
				tmpset.clear();
				break;
			}
		}
		System.out.format("-------\n%d file(s) created\n\n", count);
		
		return 0;
	}
	/**
	 * 0:1分WIN　1:時間 WIN
	 */
	private int LengthCode=WIN_FILE_1MIN;
	/**
	 * 
	 * @param lengthcode
	 */
	public static final int WIN_FILE_1MIN = 0;
	public static final int WIN_FILE_1HOUR = 1;
	
	public void setLengthcode(int lengthcode) {
		LengthCode = lengthcode;
	}
	public void clear(){
		WinTimeValue.clear();
		SecChunk.clear();
	}
}
